/*
    Matali Physics Demo
    Copyright (c) 2011 KOMIRES Sp. z o. o.
 */
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Komires.MataliPhysics;

namespace MataliPhysicsDemo
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class SkyDraw1
    {
        Demo demo;
        PhysicsScene scene;
        string instanceIndexName;

        string worldViewProjectionName;

        Vector3 position;
        Matrix translation;
        Matrix transform;
        Matrix projection;
        Matrix view;
        Matrix world;

        public SkyDraw1(Demo demo, int instanceIndex)
        {
            this.demo = demo;
            instanceIndexName = " " + instanceIndex.ToString();

            worldViewProjectionName = "WorldViewProjection";
        }

        public void Initialize(PhysicsScene scene)
        {
            this.scene = scene;
        }

        public void SetControllers()
        {
            PhysicsObject objectBase = scene.Factory.PhysicsObjectManager.Find("Sky" + instanceIndexName);
            if (objectBase != null)
            {
                objectBase.UserControllers.EnableDraw = false;
                objectBase.UserControllers.DrawMethods += new DrawMethod(DrawSky);
            }
        }

        public void DrawSky(DrawMethodArgs args)
        {
            PhysicsScene scene = demo.Engine.Factory.PhysicsSceneManager.Get(args.OwnerSceneIndex);
            PhysicsObject objectBase = scene.Factory.PhysicsObjectManager.Get(args.OwnerIndex);

            PhysicsObject physicsObjectWithActiveCamera = scene.GetPhysicsObjectsWithActiveCamera(0);

            if (physicsObjectWithActiveCamera == null) return;

            PhysicsCamera activeCamera = physicsObjectWithActiveCamera.Camera;

            if (activeCamera == null) return;

            float time = args.Time;

            activeCamera.View.GetViewMatrix(ref view);
            activeCamera.Projection.GetProjectionMatrix(ref projection);

            if (objectBase.UserTagStr != null)
            {
                demo.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
                demo.GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
                demo.GraphicsDevice.SamplerStates[0] = SamplerState.LinearClamp;

                physicsObjectWithActiveCamera.MainWorldTransform.GetPosition(ref position);
                Matrix.CreateTranslation(ref position, out translation);
                objectBase.MainWorldTransform.GetTransformMatrix(ref transform);
                Matrix.Multiply(ref transform, ref translation, out world);

                DemoMesh mesh = demo.Meshes[objectBase.UserTagStr];

                Matrix worldBone, worldViewProjection;

                if (mesh.Model != null)
                {
                    Model model = mesh.Model;

                    foreach (ModelMesh modelMesh in model.Meshes)
                    {
                        foreach (Effect effect in modelMesh.Effects)
                        {
                            transform = model.Bones[modelMesh.ParentBone.Index].Parent.Transform;
                            Matrix.Multiply(ref transform, ref world, out worldBone);
                            Matrix.Multiply(ref worldBone, ref view, out transform);
                            Matrix.Multiply(ref transform, ref projection, out worldViewProjection);
                            effect.Parameters[worldViewProjectionName].SetValue(worldViewProjection);

                            modelMesh.Draw();
                        }
                    }
                }

                demo.GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
                demo.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            }
        }
    }
}
